﻿using mozhi.smarterp.Finance.Accounts.Repository;
using mozhi.smarterp.Finance.Basedatas.Suppliers;
using mozhi.smarterp.Finance.Basedatas;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using mozhi.smarterp.Finance.Basedatas.Customers;
using mozhi.smarterp.Finance.Enums;

namespace mozhi.smarterp.Finance.Ieps.Import
{
    public class CustomerImportHandler : ImportHandlerBase<CustomerDto>
    {
        private IAccountRepository _accountRepository;

        private ICustomerAppService _customerAppService;

        public CustomerImportHandler(IServiceProvider serviceProvider) : base(serviceProvider)
        {
            _accountRepository = serviceProvider.GetService(typeof(IAccountRepository)) as IAccountRepository;
            _customerAppService = serviceProvider.GetService(typeof(ICustomerAppService)) as ICustomerAppService;
        }

        public override async Task<ImportResultDto> HandleImportData(Guid fileId)
        {
            var customers = (await GetImportData(ModuleCodeType.Customer, fileId)) as List<CustomerDto>;

            await LoadAccountsAsync(customers);

            var result = new ImportResultDto();

            result.Total = customers.Count;

            result.Errors = new List<string>();

            //开始上传供应商
            for (int i = 0; i < customers.Count; i++)
            {
                var customer = customers[i];

                var createDto = new CustomerCreateDto();
                createDto.Name = customer.Name;
                createDto.Code = customer.Code;
                createDto.ReceivableAccountId = customer.ReceivableAccountId;
                createDto.PrereceiveAccountId = customer.PrereceiveAccountId;
                createDto.Activated = true;

                try
                {
                    await _customerAppService.CreateAsync(createDto);
                    result.SuccessfulCount += 1;
                }
                catch (UserFriendlyException ex)
                {
                    result.FailureCount += 1;
                    result.Errors.Add($"第{i+1}行有错误：{ex.Message}");
                }
            }

            return result;
        }


        protected override List<CustomerDto> ConvertToData(DataSet ds)
        {
            var result = new List<CustomerDto>();

            var dt = ds.Tables[0];

            if (dt.Rows.Count == 0)
                return result;

            foreach (DataRow row in dt.Rows)
            {
                var customer = new CustomerDto();
                customer.Code = row["Code"].ToString();
                customer.Name = row["Name"].ToString();
                customer.ReceiveableAccountName = row["ReceiveableAccountName"].ToString();
                customer.PrereceiveAccountName = row["PrereceiveAccountName"].ToString();

                result.Add(customer);
            }

            return result;
        }

        #region
        private async Task LoadAccountsAsync(List<CustomerDto> customers)
        {
            var accountNames = customers.Where(x => x.ReceiveableAccountName != null).Select(x => x.ReceiveableAccountName).Distinct().ToList();

            accountNames.AddRange(customers.Where(x => x.PrereceiveAccountName != null).Select(x => x.PrereceiveAccountName).Distinct().ToList());

            var accountCodes = new List<string>();

            foreach (var accountName in accountNames)
            {
                var splits = accountName.Split(' ');

                accountCodes.Add(splits[0]);
            }

            var accounts = await _accountRepository.FindAsync(new Querys.AccountQuery() { Codes = accountCodes });

            if (accounts.Count == 0)
                return;

            foreach (var customer in customers)
            {
                if (!customer.ReceiveableAccountName.IsNullOrEmpty())
                {
                    var splits = customer.ReceiveableAccountName.Split(' ');

                    var matchAccount = accounts.FirstOrDefault(x => x.Code == splits[0] || x.Name == splits[0]);

                    customer.ReceivableAccountId = matchAccount == null ? default : matchAccount.Id;
                }

                if (!customer.PrereceiveAccountName.IsNullOrEmpty())
                {
                    var splits = customer.PrereceiveAccountName.Split(' ');

                    var matchAccount = accounts.FirstOrDefault(x => x.Code == splits[0] || x.Name == splits[0]);

                    customer.PrereceiveAccountId = matchAccount == null ? default : matchAccount.Id;
                }
            }
        }
        #endregion
    }
}
